#pragma once
#include <map>
#include "Iterator.h"
#include "UpdateObject.h"

class SceneNode : public UpdateObject
{
public:
	typedef std::map<std::string, MovableObject*> ObjectList;
	typedef ConstMapIterator<ObjectList> ObjectIterator;

public:
	SceneNode(const std::string& name, Scene* creator);
	virtual ~SceneNode();

	inline const std::string& getName() const { return mName; }
	inline Scene* getOwner() const { return mOwner; }

	inline const Vector3& getPosition() const { return mPosition; }
	inline void setPosition(const Vector3& v) { mPosition = v; NeedUpdate(); }
	
	inline const Vector3& getScale() const { return mScale; }
	inline void setScale(const Vector3& v) { mScale = v; NeedUpdate(); }

	inline const Rotator& getRotation() const { return mRotation; }
	inline void setRotation(const Rotator& v) { mRotation = v; NeedUpdate(); }

	inline const Matrix& getCachedMatrix() const { return mCachedMatrix; }
	inline const AxisAlignedBox& getBounds() const { return mAABB; }

	inline bool getVisible() const { return mVisible; }
	virtual void setVisible(bool v) { mVisible = v; }

	inline size_t getObjectNum() const { return mObjectList.size(); }

	ObjectIterator getObjectIterator() const { return ObjectIterator(mObjectList); }

	void Attach(MovableObject* obj);
	void Dettach(MovableObject* obj);
	void DettachAll();

	void NeedUpdate();
	virtual void Update(float elapsedTime);

protected:
	virtual void UpdateImpl();
	virtual void UpdateBounds();

private:
	const std::string mName;
	Scene* mOwner;
	ObjectList mObjectList;
	bool mNeedUpdate;
	bool mVisible;

	Vector3 mPosition;
	Vector3 mScale;
	Rotator mRotation;
	Matrix mCachedMatrix;
	AxisAlignedBox mAABB;
};

